package com.rfid.rfidbluetooth.manager;

import android.annotation.SuppressLint;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;


import com.rfid.rfidbluetooth.Rfid;
import com.rfid.rfidbluetooth.RfidListener;
import com.rfid.rfidbluetooth.RfidStream;

import org.greenrobot.eventbus.EventBus;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

public enum  BluetoothManager  {

    INSTANCE;

    final UUID uuid = UUID.fromString("B61BB1E5-38AF-4D54-A04B-0823E88F96A0");
//    UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
    Map<String,BluetoothClient> mBluetoothClients = new HashMap<>();
    private boolean isListening;
    private BluetoothServerSocket mServerSocket;
    BluetoothListener mListener;

    Executor mExecutor = Executors.newSingleThreadExecutor();



    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                // 处理设备，例如添加到列表中显示等。
                System.out.println("Device Found: " + device.getName() + " " + device.getAddress());
                if (mListener != null) {
                    mListener.onDeviceFound(device);
                }
            } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
                System.out.println("Discovery Finished");
                if (mListener != null) {
                    mListener.onDiscoveryFinished();
                }
            }
        }
    };

    public interface BluetoothListener {

        public void onDeviceFound(BluetoothDevice device);

        public void onDiscoveryFinished();

        public default void onConnect(boolean connect){
            System.out.println("default onConnect");
        }

        public default void onMsg(String msg){}
    }

    public void setListener(BluetoothListener listener) {
        mListener = listener;
    }


    public void connect(String mac) throws Exception {
        mac = mac.toUpperCase();
        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
        if (adapter == null) {
            throw new Exception("设备不支持蓝牙");
        }
        if (!adapter.isEnabled()) {
            throw new Exception("蓝牙没打开");
        }
        final BluetoothDevice device = adapter.getRemoteDevice(mac);
        System.out.println(device);
        BluetoothClient client = mBluetoothClients.get(mac);
        if(client != null) {
            client.close();
        }
        BluetoothSocket socket = device.createRfcommSocketToServiceRecord(uuid);
        socket.connect();
        client = new BluetoothClient(socket,mac);
        mBluetoothClients.put(mac,client);
    }



    public void registerBluetooth(Context context) {
        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        context.registerReceiver(mReceiver, filter); // mReceiver是你定义的BroadcastReceiver
    }

    public boolean startScan() {
        System.out.println("startScan");
        BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
            System.out.println("bluetoothAdapter not enable");
            return false;
        }
        bluetoothAdapter.cancelDiscovery();
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        bluetoothAdapter.startDiscovery();
        return true;
    }



    public BluetoothDevice getDevice(String mac) {
        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
        BluetoothDevice device = adapter.getRemoteDevice(mac.toUpperCase());
        return device;
    }

    public BluetoothClient getClient(String mac) {
        return mBluetoothClients.get(mac);
    }

    public String getMac() {
        if (mBluetoothClients.size() == 1) {
            return mBluetoothClients.values().iterator().next().mac;
        }
        return "";
    }

    public void actAsServer() {
        if (isListening) {
            return;
        }
        isListening = true;
        new Thread(new Runnable() {
            @Override
            public void run() {
                BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
                if(adapter == null || !adapter.isEnabled()) {
                    return;
                }
                try {
                    mServerSocket = adapter.listenUsingRfcommWithServiceRecord("liuwei", uuid);
                    while (isListening) {
                        try{
                            BluetoothSocket socket = mServerSocket.accept();
                            String mac = socket.getRemoteDevice().getAddress();
                            System.out.println("connect client mac = " + mac);
                            BluetoothClient client = new BluetoothClient(socket,mac);
                            mBluetoothClients.put(mac,client);
                            client.startReceive();
                        } catch (Exception e) {
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    public void close() {
        for (BluetoothClient client:mBluetoothClients.values()) {
            client.close();
        }
        isListening = false;
        if (mServerSocket != null) {
            try {
                mServerSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        mBluetoothClients.clear();
    }

    public class BluetoothClient {
        public BluetoothSocket mSocket;
        public String mac;
        public RfidStream rfidStream;
        RfidListener listener;

        public BluetoothClient(BluetoothSocket socket, String mac) throws IOException {
            mSocket = socket;
            this.mac = mac;
            InputStream in = mSocket.getInputStream();
            OutputStream out = mSocket.getOutputStream();
            rfidStream = new RfidStream(out,in);
        }

        public void setRfidListener(RfidListener listener) {
            this.listener = listener;
        }

        public void reqRfids(int ph) {
            mExecutor.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        rfidStream.reqRfids(1,ph);
                        List<Rfid> rfids = rfidStream.readRfids();
                        if (listener != null && rfids != null) {
                            listener.onRfids(rfids);
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            });
        }

        public void modifyEpc(int ph,int port,String epc) {
            mExecutor.execute(new Runnable() {
                @Override
                public void run() {
                    boolean s = false;
                    try {
                        s = rfidStream.modifyEpc(1,ph,port,epc);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    if (listener != null) {
                        listener.onModifyEpcResult(s);
                    }
                }
            });
        }

        public void startReceive() {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        rfidStream.listenning();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }

        public void close() {
            try {
                mSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
